/*
 * Copyright (C) 2012 Griz
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package ch.bfh.aeneas.core.connectivity;

import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.location.Location;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import ch.bfh.aeneas.core.location.PositionManager;
import ch.bfh.aeneas.core.location.PositionManager.OnPositionChangedListener;
import ch.bfh.aeneas.core.location.PositionManager.PositionManagerBinder;

/**
 * This class is responsible to keep the connection to PositionManager alive,
 * also when no other activities are listening. That should minimize waiting time
 * to get a faster position fix when starting an activity.
 * @author Griz
 */
public class PositionAliveKeeper extends Service {

    protected ServiceConnection mPositionConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName arg0, IBinder arg1) {
            mManager = ((PositionManagerBinder) arg1).getService();
            mBound = true;
            mBinding = false;
            if(mListen) {
                addListener();
            }
        }

        public void onServiceDisconnected(ComponentName arg0) {
            Log.i("PAK", "Lost service...");
            mBound = false;
            /*if(mListen) {
                removeListener();
            }//*/
            openConnection();
        }        
    };
            
    private OnPositionChangedListener mChangeListener = new OnPositionChangedListener() {
        public void onPositionChanged(Location l) {}

        public void onPositionFix(Location l) {}
    };
    
    public class PositionAliveKeeperBinder extends Binder {
        public PositionAliveKeeper getService() {
            return PositionAliveKeeper.this;
        }
    }
    private final PositionAliveKeeperBinder mBinder = new PositionAliveKeeperBinder();
    
    private PositionManager mManager;
    private boolean mBound;
    private boolean mBinding;
    private boolean mListen;
    
    @Override
    /**
     * {@inheritDoc}
     */
    public void onCreate() {
        super.onCreate();
        mBound = false;
        mBinding = false;
    }
    
    @Override
    /**
     * {@inheritDoc}
     */
    public void onStart(Intent intent, int startId) {
        onStartService(intent);
    }

    @Override
    /**
     * {@inheritDoc}
     */
    public int onStartCommand(Intent intent, int flags, int startId) {
        onStartService(intent);
        return START_STICKY;
    }
    
    private void onStartService(Intent intent) {
        openConnection(intent);
    }
    
    @Override
    /**
     * {@inheritDoc}
     */
    public IBinder onBind(Intent intent) {
        openConnection(intent);
        return mBinder;
    }
    
    @Override
    /**
     * {@inheritDoc}
     */
    public void onDestroy() {
        removeListener();
        closeConnection();        
        super.onDestroy();
    }
    
    private void addListener() {
        mManager.addOnLocationChangedListener(mChangeListener);
    }
    
    private void removeListener() {
        mManager.removeOnLocationChangedListener(mChangeListener);
    }
    
    private void closeConnection() {
        if(mBound) {
            unbindService(mPositionConnection);
        }
    }
    
    private void openConnection(Intent intent) {
        if(intent.hasExtra("listen")) {
            mListen = intent.getBooleanExtra("listen", false);
        }
        openConnection();
    }
    
    private void openConnection() {
        if(!mBound && !mBinding) {
            mBinding = true;
            bindService(new Intent(this, PositionManager.class), mPositionConnection, Context.BIND_AUTO_CREATE);
        }
    }
}
